package JET.Frames;

import JET.geom.Vec2d;
import JET.graphics.GraphicHelper;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JPanel;

/**
 *
 * @author 057Ry
 */
public class ArrowPanel extends JPanel {

    private Vec2d vector;
    private Vec2d center;

    private ArrayList<ArrowPanelListener> listeners = new ArrayList<ArrowPanelListener>();

    public ArrowPanel() {
        super();
        this.addComponentListener(new ArrowPanelComponentListener(this));
        this.addMouseListener(new ArrowPanelMouseListener(this));
        this.addMouseMotionListener(new ArrowPanelMouseMotionListener(this));
        
        vector = new Vec2d(getWidth()/2, 0.0);
        center = new Vec2d(getWidth()/2, getHeight()/2);
        this.setBackground(Color.WHITE);
    }

    public void addArrowPanelListener(ArrowPanelListener l) {
        if (!listeners.contains(l))
            listeners.add(l);
    }
    public void removeArrowPanelListener(ArrowPanelListener l) {
        listeners.remove(l);
    }

    public void notifyArrowPanelStateChanged() {
        for(ArrowPanelListener l : listeners)
            l.arrowPanelStateChanged(vector.x, vector.x);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;

        g2d.setColor(Color.GREEN);
        GraphicHelper.drawArrow(g2d, center, vector, 2);
    }

    public void findCenter() {
        vector = new Vec2d(getWidth()/2, 0.0);
        center = new Vec2d(getWidth()/2, getHeight()/2);
        repaint();
    }

    public void setVector(double x, double y)
    {
        vector.setX(x);
        vector.setY(y);
        
        notifyArrowPanelStateChanged();
        repaint();
    }

    public Vec2d getVector()
    {
        Vec2d result = new Vec2d(vector);
        result.sub(center);
        return result;
    }
    public double getLength()
    {
        return getVector().getMagnitude();
    }
    public double getAngleX()
    {
        double angle = getVector().getAngleX();
        if (angle==0)
            return angle;
        else
            return (Math.PI*2)-getVector().getAngleX();
    }

    public void setAngleX(double a)
    {
        a = (Math.PI*2)-a;
        
        Vec2d vec = new Vec2d(getLength(), 0.0);
        vec.rotate(a);
        vector.become(vec);
        vector.add(center);

        notifyArrowPanelStateChanged();
        repaint();
    }
    public void setLength(double l)
    {
        Vec2d vec = getVector().getNormalized();
        vec.scale(l);
        vector.become(vec);
        vector.add(center);
        
        notifyArrowPanelStateChanged();
        repaint();
    }
    public void setArrowVector(Vec2d vec, boolean notifyOfChange)
    {
        vector.become(vec);
        vector.add(center);

        if (notifyOfChange)
            notifyArrowPanelStateChanged();
        repaint();
    }

    class ArrowPanelMouseListener implements MouseListener
    {
        ArrowPanel owner;

        public ArrowPanelMouseListener(ArrowPanel ap)
        {
            owner = ap;
        }

        public void mouseClicked(MouseEvent e){
            owner.setVector(e.getX(), e.getY());
        }
        public void mousePressed(MouseEvent e) {
            owner.setVector(e.getX(), e.getY());
        }
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}

    }
    
    class ArrowPanelMouseMotionListener implements MouseMotionListener
    {
        ArrowPanel owner;

        public ArrowPanelMouseMotionListener(ArrowPanel ap)
        {
            owner = ap;
        }

        public void mouseDragged(MouseEvent e) {
            owner.setVector(e.getX(), e.getY());
        }
        public void mouseMoved(MouseEvent e) {}
    }

    class ArrowPanelComponentListener implements ComponentListener
    {
        ArrowPanel owner;

        public ArrowPanelComponentListener(ArrowPanel ap)
        {
            owner = ap;
        }

        public void componentResized(ComponentEvent e)
        {
            owner.findCenter();
        }
        public void componentMoved(ComponentEvent e) {}
        public void componentShown(ComponentEvent e) {}
        public void componentHidden(ComponentEvent e) {}
    }
}

